<?php

namespace App\Task;

use App\Model\Payment;
use App\Model\SystemOrderDay;
use App\Model\SystemOrderRefund;
use Hyperf\DbConnection\Db;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\ApplicationContext;
use Psr\Log\LoggerInterface;

class RefundPaymentTask
{
    protected LoggerInterface $logger;
    public function __construct(protected LoggerFactory $loggerFactory)
    {
        $this->logger = $this->loggerFactory->get('log', 'refundStatistics');
    }

    public function execute()
    {
        $container = ApplicationContext::getContainer();
        $redis = $container->get(\Hyperf\Redis\RedisFactory::class)->get('default');
        $this->logger->info(date('Y-m-d H:i:s') . '------------------------重新统计有退款订单的日期');
        try {
            $orderKey =  'refund_order';
            $keyData = $redis->get($orderKey);
            if(!empty($keyData)){
//                $redis->del($orderKey);
                $this->logger->info('存在处理中的订单进程');
                $this->logger->info(date('Y-m-d H:i:s') . '------------------------结束定时获取订单进行上报');
                return;
            }else{
                $redis->set($orderKey,1);
            }
            //休息40秒再执行
            sleep(40);
            //获取需要有退款单的日期
            $refundData = SystemOrderRefund::query()->select(['id','date'])->where('status',1)->get()->toArray();

            if(!empty($refundData)){

                $refundDate = [];
                $refundIds = [];
                foreach ($refundData as $refundDatum){
                    $refundDate[] = $refundDatum['date'];
                    $refundIds[] = $refundDatum['id'];
                }
                $refundDate = array_unique($refundDate);
                $refundDate = array_values($refundDate);

                if(!empty($refundDate)){
                    foreach ($refundDate as $refundDatum){

                        $startDate = date('Y-m-d 00:00:00',strtotime($refundDatum));
                        $endDate = date("Y-m-d 23:59:59",strtotime($refundDatum));
                        $this->logger->info('开始时间为：'.$startDate);
                        $this->logger->info('结束时间为：'.$endDate);
                        ;
                        //获取需要处理的订单
                        $paymentData = Payment::query()
                            ->where('pay_time','>=',$startDate)
                            ->where('pay_time','<=',$endDate)
                            ->orderBy('pay_time')
                            ->get();
                        if($paymentData->isNotEmpty()) {
                            //判断是否
                            $this->logger->info('订单的数据为数量为：', [count($paymentData)]);
                            $date_Arr = [];
                            foreach ($paymentData as $paymentDatum) {
                                $pay_time = $paymentDatum->pay_time;
                                $amount = $paymentDatum->amount;
                                $date = date("Y-m-d",strtotime($pay_time));
                                $hour = date("H",strtotime($pay_time));
                                //获取此订单的日期和时间
                                $spread_id = $paymentDatum->spread_id;
                                $playlet_id = $paymentDatum->playlet_id ?? 0;
                                $ad_id = $paymentDatum->ad_id ?? 0;
                                $applet_id = $paymentDatum->applet_id ?? 0;
                                //创建一个关于日期的数组
                                if(empty($date_Arr[$date])){
                                    $date_Arr[$date] = [];
                                }
                                //创建一个关于日期和小时的数组
                                if(empty($date_Arr[$date][$hour])){
                                    $date_Arr[$date][$hour] = [];
                                }
                                //订单金额
                                $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'order_amount',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                                //订单总数
                                $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'order_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                                //待支付
                                if ($paymentDatum->status == 1) {
                                    $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'order_wait_pay_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                                }
                                //已支付
                                if ($paymentDatum->status == 2 || $paymentDatum->status == 4) {
                                    $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'order_pay_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                                    if($paymentDatum->first_recharge == 'Y'){
                                        $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'first_user_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                                        $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'first_user_pay_amonut',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                                    }
                                    if($paymentDatum->today_first_recharge == 'Y'){
                                        $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'today_first_user_pay_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                                        $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'today_first_user_pay_amonut',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                                    }
                                    if($paymentDatum->today_after_recharge == 'Y'){
                                        $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'today_after_user_pay_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                                        $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'today_after_user_pay_amonut',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                                    }
                                    //虚拟支付
                                    if ($paymentDatum->pay_type == 1) {
                                        $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'order_virtually_pay_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                                        $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'order_virtually_pay_amount',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                                    }
                                    //微信支付
                                    if ($paymentDatum->pay_type == 2) {
                                        $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'order_wx_pay_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                                        $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'order_wx_pay_amonut',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                                    }

                                    //抖音支付
                                    if ($paymentDatum->pay_type == 3 ||$paymentDatum->pay_type == 4 || $paymentDatum->pay_type == 5 ) {
                                        $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'dy_pay_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                                        $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'dy_pay_amount',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                                    }

                                    //已退款
                                    if ($paymentDatum->status == 4) {
                                        $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'order_return_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                                        $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'order_return_pay_amount',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                                    }
                                }
                            }

                            $insertInfo = array();
                            $deleteInfo = array();
                            $insertAllData = array();
                            //日期数组
                            foreach ($date_Arr as $selectDate => $hourInfo) {
                                //日期下时间数组
                                foreach ($hourInfo as $hour => $hourItem) {
                                    //每个小时下
                                    $deleteInfo[$selectDate][] = $hour;
                                    foreach ($hourItem as $spread_key => $numberInfo) {
                                        $spreadData = explode("|###|", $spread_key);
                                        $spread_id = $spreadData[0];
                                        $playlet_id = $spreadData[1];
                                        $ad_id = $spreadData[2];
                                        $applet_id = $spreadData[3];
                                        $coutArray = [];
                                        foreach ($numberInfo as $number => $item) {
                                            $coutArray[$number] = $item;
                                        }
                                        $comData = [
                                            'data_spread_id' => $spread_id,
                                            'playlet_id' => $playlet_id,
                                            'ad_id' => $ad_id,
                                            'applet_id' => $applet_id,
                                            'date'  => $selectDate,
                                            'hour'  => $hour,
                                        ];
                                        $insertmoreData = $comData+$coutArray;
                                        $insertInfo[] = $insertmoreData;
                                    }
                                }
                            }
                            if(!empty($insertInfo)){
                                foreach ($insertInfo as $item){
                                    $insertAllData[] = [
                                        'date' => $item['date'],
                                        'hour' => $item['hour'],
                                        'data_spread_id' => $item['data_spread_id'],
                                        'playlet_id' => $item['playlet_id'],
                                        'applet_id' => $item['applet_id'],
                                        'ad_id' => $item['ad_id'],
                                        'first_user_count' => $item['first_user_count'] ?? 0,
                                        'today_first_user_pay_amonut' => $item['today_first_user_pay_amonut'] ?? 0,
                                        'today_first_user_pay_count' => $item['today_first_user_pay_count'] ?? 0,
                                        'today_after_user_pay_amonut' => $item['today_after_user_pay_amonut'] ?? 0,
                                        'today_after_user_pay_count' => $item['today_after_user_pay_count'] ?? 0,
                                        'first_user_pay_amonut' => $item['first_user_pay_amonut'] ?? 0,
                                        'order_count' => $item['order_count'] ?? 0,
                                        'order_wait_pay_count' => $item['order_wait_pay_count'] ?? 0,
                                        'order_pay_count' => $item['order_pay_count'] ?? 0,
                                        'order_cannel_count' => $item['order_cannel_count'] ?? 0,
                                        'order_return_count' => $item['order_return_count'] ?? 0,
                                        'order_wx_pay_count' => $item['order_wx_pay_count'] ?? 0,
                                        'order_virtually_pay_count' => $item['order_virtually_pay_count'] ?? 0,
                                        'order_amount' => $item['order_amount'] ?? 0,
                                        'order_wx_pay_amonut' => $item['order_wx_pay_amonut'] ?? 0,
                                        'order_virtually_pay_amount' => $item['order_virtually_pay_amount'] ?? 0,
                                        'order_return_pay_amount' => $item['order_return_pay_amount'] ?? 0,
                                        'dy_pay_count' => $item['dy_pay_count'] ?? 0,
                                        'dy_pay_amount' => $item['dy_pay_amount'] ?? 0
                                    ];
                                }

                                if(!empty($deleteInfo)) {

                                    foreach ($deleteInfo as $date => $hourInfo) {
                                        $this->logger->info('删除今日',[$date]);
                                        SystemOrderDay::query()->where(['date' => $date])->delete();
                                    }
                                    if(!empty($insertAllData)){
                                        $this->logger->info('插入数据',[count($insertAllData)]);
                                        $commonData = [];
                                        $count = count($insertAllData);
                                        foreach ($insertAllData as $key  => $val){
                                            $commonData[] = $val;
                                            if(count($commonData) > 2000){
                                                Db::table('system_order_day')->insert($commonData);
                                                $commonData = array();
                                            }
                                            if($key+1 == $count){
                                                Db::table('system_order_day')->insert($commonData);
                                                $commonData = array();
                                            }
                                        }
                                    }
                                }
                            }
                        } else{
                            $this->logger->info('没有订单需要处理');
                        }
                    }

                    if(!empty($refundIds)){
                        $this->logger->info('更新需要有退款订单的日期',$refundIds);
                        SystemOrderRefund::query()->whereIn('id',$refundIds)->update(['status' => 2]);
                    }

                }else{
                    $this->logger->info('整合后没有退款日期订单需要处理');
                }

            }else{
                $this->logger->info('没有退款日期订单需要处理');
            }
            $redis->del($orderKey);

        }catch (\Exception $e){
            $redis->del($orderKey);
            $this->logger->error('请求订单|错误：' . $e->getLine() . '|' . $e->getMessage());
        }
        $this->logger->info(date('Y-m-d H:i:s') . '------------------------结束定时获取订单数据');
    }


    public function countOrder($statisData,$arrName,$spread_id,$playlet_id,$ad_id,$applet_id){

//        $keyName = $spread_id.'_'.$playlet_id.'_'.$ad_id.'_'.$applet_id;
        $keyName = $spread_id.'|###|'.$playlet_id.'|###|'.$ad_id.'|###|'.$applet_id;

        if (!empty($statisData[$keyName][$arrName])) {
            $statisData[$keyName][$arrName] += 1;
        } else {
            $statisData[$keyName][$arrName] = 1;
        }
        return $statisData;
    }
    public function countOrderAmount($statisData,$arrName,$spread_id,$playlet_id,$ad_id,$applet_id,$amonut){

//        $keyName = $spread_id.'_'.$playlet_id.'_'.$ad_id.'_'.$applet_id;
        $keyName = $spread_id.'|###|'.$playlet_id.'|###|'.$ad_id.'|###|'.$applet_id;

        if (!empty($statisData[$keyName][$arrName])) {
            $statisData[$keyName][$arrName] += $amonut;
        } else {
            $statisData[$keyName][$arrName] = $amonut;
        }
        return $statisData;
    }
}